#include "QmitkDataGeometry3DInteractor.h"
// #include <qaction.h>

#include <mitkGlobalInteraction.h>
#include <mitkProperties.h>
#include <mitkStringProperty.h>
#include <mitkIDataStorageService.h>
#include <mitkDataNodeFactory.h>
#include <mitkSurface.h>
#include <mitkSurfaceGLMapper2D.h>



#include <mitkNodePredicateDataType.h>

#include <berryIEditorPart.h>
#include <berryIWorkbenchPage.h>
#include <berryPlatform.h>
#include <itkObject.h>
#include <itkCommand.h>

#include "WxPointedSticksMapper2D.h"
#include "WxDoNothingMapper.h"
#include "WxObjectOrientationMarker.h"
#include "WxObjectOrientationMarkerMapper3D.h"
#include "mitkNodePredicateOr.h"


////////////////////////////////////////////////////////////
#include "mitkExtractDirectedPlaneImageFilter.h"
#include "mitkGeometry2DData.h"
#include "mitkGeometry2DDataVtkMapper3D.h"
#include "WxTexturedSurfaceVtkMapper3D.h"




QmitkDataGeometry3DInteractor::QmitkDataGeometry3DInteractor()
{
    m_IsControlling=false;
}
QmitkDataGeometry3DInteractor::~QmitkDataGeometry3DInteractor()
{
}

void QmitkDataGeometry3DInteractor::Activated()
{
   m_ItkEventListener = new ItkEventListener();
   std::vector<mitk::DataNode*> selection = this->GetDataManagerSelection();
   this->OnSelectionChanged( selection );

}

void QmitkDataGeometry3DInteractor::Deactivated()
{
  std::vector<mitk::DataNode*> selection;
  this->OnSelectionChanged( selection );
  m_ItkEventListener->Delete();
}


void QmitkDataGeometry3DInteractor::CreateQtPartControl( QWidget* parent )
{
  m_Controls = new Ui::QmitkDataGeometry3DInteractorControls;
  m_Controls->setupUi(parent);
  m_Controls->cmbImage->SetDataStorage(this->GetDefaultDataStorage());
  connect( (QObject*)(m_Controls->btnCtrlData), SIGNAL(clicked()),(QObject*) this, SLOT(ControlData()) );
  connect( (QObject*)(m_Controls->btnTestPlane), SIGNAL(clicked()),(QObject*) this, SLOT(AddTestPlane()) );
}

void QmitkDataGeometry3DInteractor::OnSelectionChanged( std::vector<mitk::DataNode*> nodes )
{
    mitk::DataNode* selectedNode = 0;
    if(nodes.size() > 0)
      selectedNode = nodes.front();

      disconnect( m_Controls->cmbImage, SIGNAL( OnSelectionChanged( const mitk::DataNode* ) ),
               this, SLOT( OnComboBoxSelectionChanged( const mitk::DataNode* ) ) );

      m_Controls->cmbImage->setCurrentIndex( m_Controls->cmbImage->Find(selectedNode) );

      connect( m_Controls->cmbImage, SIGNAL( OnSelectionChanged( const mitk::DataNode* ) ),
        this, SLOT( OnComboBoxSelectionChanged( const mitk::DataNode* ) ) );


    mitk::DataStorage* ds=this->GetDefaultDataStorage();
         if(m_ObjectOrientationMarkerInteractor.IsNull()) return;
         mitk::WxObjectOrientationMarkerInteractor* oomi=m_ObjectOrientationMarkerInteractor;
         mitk::DataNode* node=oomi->GetObjectOrientationMarkerNode();
         if(node) ds->Remove(node);
         mitk::GlobalInteraction::GetInstance()->RemoveListener(m_ObjectOrientationMarkerInteractor);
         m_CtrlDataNode=NULL;
         m_IsControlling=false;
         m_Controls->btnCtrlData->setText(QString::fromStdString("选择被控制物体"));
         m_Controls->cmbImage->setEnabled(true);

}

bool QmitkDataGeometry3DInteractor::IsExclusiveFunctionality() const
{
  return true;
}

void QmitkDataGeometry3DInteractor::NodeRemoved( const mitk::DataNode* node )
{

}
void QmitkDataGeometry3DInteractor::ControlData()
{
   if(m_IsControlling)
   {
       mitk::DataStorage* ds=this->GetDefaultDataStorage();
       mitk::WxObjectOrientationMarkerInteractor* oomi=m_ObjectOrientationMarkerInteractor;
       mitk::DataNode* node=oomi->GetObjectOrientationMarkerNode();
       if(node) ds->Remove(node);
       mitk::GlobalInteraction::GetInstance()->RemoveListener(m_ObjectOrientationMarkerInteractor);
       m_CtrlDataNode=NULL;
       m_IsControlling=false;
       m_Controls->btnCtrlData->setText(QString::fromStdString("选择被控制物体"));
       m_Controls->cmbImage->setEnabled(true);
   }
   else
   {
       mitk::DataStorage* ds=this->GetDefaultDataStorage();
       mitk::DataNode* node=m_Controls->cmbImage->GetSelectedNode();
       m_CtrlDataNode=node;
       mitk::WxObjectOrientationMarker::Pointer marker= mitk::WxObjectOrientationMarker::New();
       marker->RefGeometry(node->GetData()->GetGeometry());
       mitk::DataNode::Pointer markerNode=mitk::DataNode::New();
       markerNode->SetData(marker);
       markerNode->SetMapper(mitk::BaseRenderer::Standard3D,mitk::WxObjectOrientationMarkerMapper3D::New());
       ds->Add(markerNode,node);
       mitk::WxObjectOrientationMarkerInteractor::Pointer oomi= mitk::WxObjectOrientationMarkerInteractor::New("ObjectOrientationMarkerInteractor",markerNode);
       m_ObjectOrientationMarkerInteractor=oomi;
       mitk::GlobalInteraction::GetInstance()->AddListener(m_ObjectOrientationMarkerInteractor);
       m_IsControlling=true;
       m_Controls->btnCtrlData->setText(QString::fromStdString("释放被控制物体"));
       m_Controls->cmbImage->setEnabled(false);
   }

}

void QmitkDataGeometry3DInteractor::AddTestPlane()
{
    mitk::WxObjectOrientationMarkerInteractor* oomi= m_ObjectOrientationMarkerInteractor;
    //vtkPlaneSource * planeSource=vtkPlaneSource::New();
  //  mitk::Geometry3D* g3d=oomi->GetObjectOrientationMarker()->GetGeometry();
   // mitk::Point3D ori=g3d->GetOrigin();
   // mitk::Point3D point1=g3d->GetOrigin()+g3d->GetAxisVector(1)*5;
   // mitk::Point3D point2=ori+g3d->GetAxisVector(2);
////    planeSource->SetOrigin(ori[0],ori[1],ori[2]);
////    planeSource->SetPoint1(point1[0],point1[1],point1[2]);
////    planeSource->SetPoint2(point2[0],point2[1],point2[2]);
////    planeSource->Update();
////    mitk::Surface::Pointer surface=mitk::Surface::New();
////    surface->SetVtkPolyData(planeSource->GetOutput());


////    mitk::DataNode::Pointer node = mitk::DataNode::New();
////    node->SetData(surface);
////    node->SetName("US_ClipPlane");
////    node->SetColor(0.8,0.1,0.1);
////    node->SetProperty("layer",mitk::IntProperty::New(1000));
////    node->SetVisibility(true);
////    // crossBallNode->SetMapper(mitk::BaseRenderer::Standard2D,mitk::WxDoNothingMapper::New());
////    this->GetDataStorage()->Add(node);
////    planeSource->Delete();



//    mitk::NodePredicateOr::Pointer p = mitk::NodePredicateOr::New();
//    p->AddPredicate(mitk::NodePredicateDataType::New("Image"));
//    mitk::DataStorage::SetOfObjects::ConstPointer all = GetDefaultDataStorage()->GetSubset(p);
//    mitk::Image* image=NULL;
//    mitk::DataNode *imageNode;
//    for (mitk::DataStorage::SetOfObjects::ConstIterator it = all->Begin(); it != all->End(); ++it)
//    {
//        imageNode = it->Value();
//        image=dynamic_cast<mitk::Image*>(imageNode->GetData());
//        if(image!=NULL)
//            break;
//    }

//    mitk::Vector3D vori=ori-image->GetGeometry()->GetOrigin();
//    vtkMatrix4x4 *m=vtkMatrix4x4::New();
//    m->Identity();

//    mitk::Vector3D vx=g3d->GetAxisVector(0); /*MITK_INFO<<vx.GetNorm();*/ vx.Normalize();
//    mitk::Vector3D vy=g3d->GetAxisVector(1); /*MITK_INFO<<vy.GetNorm();*/ vy.Normalize();
//    mitk::Vector3D vz=g3d->GetAxisVector(2); /*MITK_INFO<<vz.GetNorm();*/ vz.Normalize();

//    int i,j;
//    for(i=0;i<3;++i)
//        m->SetElement(i, 0, vx[i]);
//    for(i=0;i<3;++i)
//        m->SetElement(i, 1, vy[i]);
//    for(i=0;i<3;++i)
//        m->SetElement(i, 2, vz[i]);

//    for(i=0;i<3;++i)
//      m->SetElement(i, 3, g3d->GetIndexToWorldTransform()->GetOffset()[i]);
//    m->Modified();

//     mitk::Geometry3D* g3dI=image->GetGeometry();
//    vtkMatrix4x4 *m2=vtkMatrix4x4::New();
//    m2->Identity();

//    mitk::Vector3D vx2=g3dI->GetAxisVector(0); /*MITK_INFO<<vx.GetNorm();*/ vx2.Normalize();
//    mitk::Vector3D vy2=g3dI->GetAxisVector(1); /*MITK_INFO<<vy.GetNorm();*/ vy2.Normalize();
//    mitk::Vector3D vz2=g3dI->GetAxisVector(2); /*MITK_INFO<<vz.GetNorm();*/ vz2.Normalize();

//    for(i=0;i<3;++i)
//        m2->SetElement(i, 0, vx2[i]);
//    for(i=0;i<3;++i)
//        m2->SetElement(i, 1, vy2[i]);
//    for(i=0;i<3;++i)
//        m2->SetElement(i, 2, vz2[i]);

//    for(i=0;i<3;++i)
//      m2->SetElement(i, 3, g3dI->GetIndexToWorldTransform()->GetOffset()[i]);

//    m2->Invert();
//    m2->Modified() ;

//    vtkMatrix4x4::Multiply4x4(m2,m,m);
//    vtkImageData* VImage=image->GetVtkImageData();

//    vtkImageReslice* ImageReslice=vtkImageReslice::New();
//    ImageReslice->SetInput(VImage);
//    ImageReslice->SetOutputDimensionality(2);

//    ImageReslice->SetResliceAxesOrigin(vori[0],vori[1],vori[2]);

//    ImageReslice->SetInterpolationModeToLinear();
//    ImageReslice->SetBackgroundLevel( -1023);
//    ImageReslice->SetResliceAxes(m);
// // ImageReslice->SetResliceTransform(image->GetGeometry()->GetVtkTransform()->GetLinearInverse());
//    ImageReslice->Update();


//    mitk::Image::Pointer imageintree=mitk::Image::New();
//    imageintree->Initialize(ImageReslice->GetOutput());
//    imageintree->SetSlice(ImageReslice->GetOutput()->GetScalarPointer(),0,0,0);
//    imageintree->Update();

//    mitk::DataNode::Pointer outnode=mitk::DataNode::New();
//    outnode->SetData(imageintree);
//    outnode->SetName("Curveimagedata");
//    outnode->Update();

//    GetDefaultDataStorage()->Add( outnode );

//    mitk::RenderingManager::GetInstance()->RequestUpdateAll();
//    m->Delete();
//    m2->Delete();

//    mitk::PlaneGeometry::Pointer viewPlaneGeometry=mitk::PlaneGeometry::New();
//    viewPlaneGeometry->SetOrigin(ori-vx*100);
//    viewPlaneGeometry->InitializeStandardPlane(200,300,vx,vz);

//    mitk::Geometry2DData::Pointer g2dData1=mitk::Geometry2DData::New();
//    g2dData1->SetGeometry2D(viewPlaneGeometry);


//    mitk::Geometry2DDataVtkMapper3D::Pointer g3dm=mitk::Geometry2DDataVtkMapper3D::New();
//    g3dm->SetDataStorageForTexture(GetDefaultDataStorage());


  //  m_ItkEventListener->SetImageExtractFrom(image);
//    f->SetWorldGeometry(viewPlaneGeometry);
//    f->Update();
//    mitk::Image* image2=f->GetOutput();


  //  mitk::DataNode::Pointer  outnode=mitk::DataNode::New();
   // outnode->SetData(image2);
  //  outnode->SetName("Test_plane_data_image");
 //   outnode->Update();
  //  GetDefaultDataStorage()->Add( outnode );



   //   mitk::Plane::Pointer plane=mitk::Plane::New();
 //     m_ItkEventListener->SetPlane(plane);
   //   m_ItkEventListener->SetPlaneWidth(300);
  //    m_ItkEventListener->SetPlaneLength(300);
//    mitk::Point3D pos3d=ori+vz*150;
//    mitk::AffineTransform3D::Pointer affineTransform =mitk::AffineTransform3D::New();
//    mitk::Vector3D pos;
//    pos.Set_vnl_vector(pos3d.Get_vnl_vector());
//    affineTransform->SetOffset(pos);
//    mitk::AffineTransform3D::MatrixType m;
//    m.GetVnlMatrix().set_column(0,vx.Get_vnl_vector());
//    m.GetVnlMatrix().set_column(1,vz.Get_vnl_vector());
//    m.GetVnlMatrix().set_column(2,vy.Get_vnl_vector());
//    affineTransform->SetMatrix(m);
//    affineTransform->Modified();
//    plane->GetGeometry()->SetIndexToWorldTransform(affineTransform);
//    plane->GetGeometry()->SetOrigin(pos3d);
//    plane->GetGeometry()->Modified();
//    plane->Modified();
//    plane->SetExtent(200,300);


//    mitk::DataNode::Pointer outnode=mitk::DataNode::New();
//    outnode->SetData(plane);
//    outnode->SetName("Test_plane_data");

//    outnode->SetMapper(mitk::BaseRenderer::Standard3D,mitk::WxTexturedSurfaceVtkMapper3D::New());
//    GetDefaultDataStorage()->Add( outnode );

     mitk::DataNode* node= GetDefaultDataStorage()->GetNamedNode("widget7Plane");
     m_ItkEventListener->m_Geometry3D=node->GetData()->GetGeometry();
     m_ObserverTag=oomi->GetObjectOrientationMarker()->AddObserver(itk::ModifiedEvent(), m_ItkEventListener);


}
